from selenium.webdriver.common.by import By
from config import function_dic, type_list
from common.processingLog import log
from common.operateWebdriver import OperateWebdrive
from common.processingTestData import ProcessingTestData


class Factory:
    def __init__(self):
        self.webdriver_opr = None

    def init_webdriver_opr(self):
        """网页操作入口"""
        self.webdriver_opr = OperateWebdrive()

    def title_is_exist(self, data, title):
        """
        判断data（字典形式）中是否存在title键，存在则返回True和title名，否则返回False和错误信息
        :param data: 字典形式的一组数据（excel中的一行数据） {id:xx,keyword:xx,...}
        :param title: 列名
        :return: 列对应的值，如 title：keyword（对应的值是点击），返回的值：点击
        """
        if title not in data:
            error = "找不到[{}]对象，请检查用例".format(title)
            # log.error(error)  # 日志
            return False, error
        else:
            value = data[title]
            return True, value

    def excute_keyword(self, data):
        """
        处理excel中keyword列，获取OperateWebdrive类中的方法
        :param data:关键字对应的方法 {id:xx,keyword:xx,...}
        :return: 是否找到方法，True为找到，并返回方法名，Fales为找不到
        """
        isOK, keyword = self.title_is_exist(data, "keyword")

        if isOK:
            # 如果用例行是调用用例，直接略过
            if keyword == '调用用例':
                return None,None

            for i in function_dic.keys():
                if i == keyword:
                    function_name = function_dic[i]
                    return True, function_name
            else:
                error = "找不到【{}】方法，该方法未定义，请检查配置文件。".format(keyword)
                # log.error(error)  # 日志
                return False, error
        else:
            return False, keyword

    def excute_type(self, data):
        """
        处理excel中type列
        :param data: type列对应的值 {id:xx,keyword:xx,...}
        :return:查看它的值是否存在配置文件中，存在则返回True和其值，否则返回Fales
        """
        isOK, type = self.title_is_exist(data, "type")

        if isOK:
            # 判断type的值，要么在type_list中，要么为空
            if type.upper() in type_list:
                return True, type.upper()
            elif type == '':  # 运行为空的情况
                return True, type
            else:
                error = "找不到type对应的值[{}]，请检查用例。".format(type)
                # log.error(error)
                return False, error
        else:
            return False, type

    def excute_locator(self, data):
        """
        处理excel中locator列(定位的对象)，看它的的值是否存在，存在则返回True和其值，否则返回Fales
        :param data: {id:xx,keyword:xx,...}
        :return:
        """
        # 看type的值和locator类是否有值
        t_isOK, type = self.excute_type(data)
        l_isOK, locator = self.title_is_exist(data, "locator")

        if t_isOK and l_isOK:
            # 判断locator的值是否存在
            if locator != "" and locator is not None:

                if type == "URL" or type == "JS" or type == "":
                    locator = locator
                elif type == "ID":
                    locator = (By.ID, locator)
                elif type == "NAME":
                    locator = (By.NAME, locator)
                elif type == "XPATH":
                    locator = (By.XPATH, locator)
                elif type == "CLASS":
                    locator = (By.CLASS_NAME, locator)
                elif type == "CSS":
                    locator = (By.CSS_SELECTOR, locator)
                elif type == "TAG_NAME":
                    locator = (By.TAG_NAME, locator)
                elif type == "LINK_TEXT":
                    locator = (By.LINK_TEXT, locator)
                elif type == "PARTIAL_LINK_TEXT":
                    locator = (By.PARTIAL_LINK_TEXT, locator)

                return True, locator

            else:
                return True, locator

        else:
            return False, locator

    def excute_input(self, data):
        """
        处理excel中input列
        :param data:{id:xx,keyword:xx,...}
        :return:
        """
        isOK, input = self.title_is_exist(data, "input")
        if isOK:
            return True, input
        else:
            return False, input

    def excute_check(self, data):
        """
        处理excel中check列，查看检查点是否通过
        :param data:{id:xx,keyword:xx,...}
        :return:
        """
        isOK, check = self.title_is_exist(data, "check")
        if isOK:
            return True, check
        else:
            return False, check

    def get_webdriver_opr(self, k_result):
        function = getattr(self.webdriver_opr, k_result)
        return function

    def execute_webdriver_opr(self, data):
        """
        执行OperateWebdrive类中的方法
        :param data: {id:xx,keyword:xx,...}
        :return:
        """
        k_isOK, k_result = self.excute_keyword(data)
        c_isOK, c_result = self.excute_check(data)
        l_isOK, l_result = self.excute_locator(data)
        input_isOK, input_reuslt = self.excute_input(data)

        if k_isOK and l_isOK and input_isOK and c_isOK:
            # 如果keyword是打开网页，则先初始化init_webdriver_opr
            if k_result == "get_url":
                self.init_webdriver_opr()

            if hasattr(self.webdriver_opr, k_result):
                function = self.get_webdriver_opr(k_result)

                # locator不为空，input为空，check为空
                if l_result != '' and input_reuslt == '' and c_result == '':
                    result = function(l_result)  # 执行方法

                # locator不为空，input不为空，check为空
                elif l_result != '' and input_reuslt != '' and c_result == '':
                    result = function(l_result, input_reuslt)  # 执行方法

                # locator不为空，input为空，check为不空
                elif l_result != '' and input_reuslt == '' and c_result != '':
                    result = function(l_result, c_result)  # 执行方法

                # locator为空，input不为空，check为空
                elif l_result == '' and input_reuslt != '' and c_result == '':
                    result = function(input_reuslt)  # 执行方法

                # locator为空，input为空，check为空
                elif l_result == '' and input_reuslt == '' and c_result == '':
                    result = function()  # 执行方法

                else:
                    error = "传递的数据locator【{}】、input【{}】、check【{}】有误，请检查用例。" \
                        .format(l_result, input_isOK, classmethod)
                    # log.error(error)  # 日志
                    return False, error

                return True, result
            else:
                error = "【{}】对应的方法定义有误，请检查配置文件。".format(k_result)
                # log.error(error)  # 日志
                return False, error

        elif k_isOK is None:
            return k_isOK,k_result

        else:
            return False, k_result



    def init_execute_case(self):
        """
        用例组装
        :return: [{sheet1:[{id:xx,keyword:xx,...},{id:xx,keyword:xx,...}]},{sheet2:[{id:xx,keyword:xx,...}]}]
        """
        print("----------初始化用例----------")
        ptd = ProcessingTestData()
        isOK, result = ptd.get_normal_data()  # 获取正常执行的用例  result -->[{sheet1:[{id:xx,keyword:xx,...},{id:xx,keyword:xx,...}]}, {sheet2:[{id:xx,keyword:xx,...}]}]
        if isOK == False:
            print("----------结束执行----------")
            # exit()
            return
        excu_cases = []
        all_cases = result
        for cases_dict in all_cases:  # cases_dict--->{sheet1:[{id:xx,keyword:xx,...},{id:xx,keyword:xx,...}]}
            for sheet, cases in cases_dict.items():  # cases--->[{id:xx,keyword:xx,...},{id:xx,keyword:xx,...}]
                # 判断用例行是否调用公共用例，与插入公共用例
                for case in cases:  # case---》{id:xx,keyword:xx,...}
                    index = cases.index(case)
                    c_isOK, c_result = ptd.init_common_case(
                        case)  # 获取公共用例  result-->[{id:xx,keyword:xx,...},{id:xx,keyword:xx,...}]
                    print(c_isOK)
                    print(result)
                    if c_isOK:
                        print("----------插入公共用例----------")
                        for i in c_result:
                            cases.insert(index + 1, i)
                            index += 1
                        print("----------插入公共用例完成----------")

                    elif c_isOK==None:
                        continue

                    else:
                        print("----------插入公共用例失败----------")
                        # exit()
                        print(c_isOK)
                        print(c_result)
                        return
                cases_dict[sheet] = cases
                excu_cases.append(cases_dict)
            print("----------初始化用例完成----------")
        return excu_cases
